#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <iostream>
#include <string>
#include <vector>
#include <list>
using namespace std; // 否则要用 std::vector

// 写实拷贝这些东西，有点没听懂
// int main()
//{
//	string s1;
//	cout << sizeof(s1) << endl;//一个类的大小
//	string s2("1234");
//	cout << sizeof(s2) << endl; //两者一样大
// }

// 初始化方式
void test_vector1()
{
    vector<int> v;
    v.push_back(1);
    v.push_back(2);
    v.push_back(3);
    v.push_back(4);

    // vector<char>
    // string
    // 区别

    for (size_t i = 0; i < v.size(); i++)
    {
        cout << v[i] << " ";
    }
    cout << endl;

    vector<int>::iterator it1 = v.begin();
    while (it1 != v.end())
    {
        cout << *it1 << " ";
        ++it1;
    }
    cout << endl;

    for (auto e : v)
    {
        cout << e << " ";
    }
    cout << endl;
}

// 构造方式
void test_vector2()
{
    vector<int> v1(10, 1);
    for (auto e : v1)
    {
        cout << e << " ";
    }
    cout << endl;

    vector<int> v2(v1.begin(), v1.end()); // 从开头的内容一直到结尾
    for (auto e : v2)
    {
        cout << e << " ";
    }
    cout << endl;

    string s1("12345");
    vector<int> v3(s1.begin(), s1.end()); // 里面存在一个隐式类型转换（char初始化vector）
    for (auto e : v3)
    {
        cout << e << " ";
    }
    cout << endl;
}

// 扩容机制
void TestVectorExpand()
{
    size_t sz;
    vector<int> v;
    v.reserve(100);
    sz = v.capacity();
    cout << "making v grow:\n";
    for (int i = 0; i < 100; ++i)
    {
        v.push_back(i);
        if (sz != v.capacity())
        {
            sz = v.capacity();
            cout << "capacity changed: " << sz << '\n';
        }
    }
}

void test_vector3()
{
    TestVectorExpand();

    vector<int> v;
    for (size_t i = 0; i < 100; i++)
    {
        v.push_back(i);
    }

    cout << v.size() << endl;
    cout << v.capacity() << endl;

    v.resize(10);
    cout << v.size() << endl;
    cout << v.capacity() << endl;

    v.shrink_to_fit();

    cout << v.size() << endl;
    cout << v.capacity() << endl;
}

void test_vector4()
{
    vector<int> v;
    v.push_back(1);
    v.push_back(2);
    v.push_back(3);
    v.push_back(4);
    for (auto e : v)
    {
        cout << e << " ";
    }
    cout << endl;

    v.insert(v.begin(), 0);

    for (auto e : v)
    {
        cout << e << " ";
    }
    cout << endl;

    // vector<int>::iterator it = find(v.begin(), v.end(), 3);
    auto it = find(v.begin(), v.end(), 3);

    v.insert(it, 30);

    for (auto e : v)
    {
        cout << e << " ";
    }
    cout << endl;

    list<int> lt;
    lt.push_back(10);
    lt.push_back(20);
    lt.push_back(30);
    lt.push_back(40);
    auto lit = find(lt.begin(), lt.end(), 3);

    if (lit != lt.end())
    {
        lt.insert(lit, 300);
    }

    for (auto e : lt)
    {
        cout << e << " ";
    }
    cout << endl;
    // 迭代器区间传的都是 左闭右开 [  )

    vector<string> vstr;
    string s1("张三");
    vstr.push_back(s1);
    vstr.push_back(string("李四")); // 单参数的构造函数支持隐式类型转换
    // 创建了一个临时的 string 对象，初始化为 "李四"，并将其通过 push_back 添加到 vstr 容器中。
    // 这里使用了 string 类的单参数构造函数，支持将 const char* 类型的字符串常量隐式转换为 string 对象。
    vstr.push_back("王五");
    // 这里直接使用了字符串字面值 "王五"，同样通过 push_back 添加到 vstr 容器中。
    // 这种方式也依赖于 string 类的单参数构造函数，可以将 const char* 类型的字符串字面值隐式转换为 string 对象。

    // 在 C++ 中，string 类的单参数构造函数允许从 const char* 类型的字符串常量或字符串字面值隐式转换为 string 对象。
    // 因此，你可以在 vector<string> 中直接使用字符串常量或字符串字面值来初始化或添加元素，编译器会自动完成类型转换工作。
    for (const auto &e : vstr)
    {
        cout << e << " ";
    }
    cout << endl;

    cout << vstr[0][0] << "x";
    cout << vstr[0][2] << endl;
}

// 三种遍历方式

// vector<char>和string的区别,能不能替换

// 扩容，vs的和

// 为什么没有find？ 因为find是通用的，

// 使用讲完后 做了两个题
// 只出现一次的数
// 杨辉三角->二维数组讲解

// #include <iostream>  // 引入输入输出流头文件
// #include <vector>    // 引入 vector 容器头文件
// #include <stdexcept> // 引入标准异常头文件
// using namespace std; // 使用标准命名空间
//
// int main() {
//	vector<int> vec = { 10, 20, 30, 40, 50 }; // 初始化一个包含五个整数的 vector
//
//	// 正常访问 vector 的元素
//	try {
//		for (size_t i = 0; i < vec.size(); ++i) {
//			cout << "Element at index " << i << " is " << vec.at(i) << endl; // 使用 at() 函数访问元素
//		}
//	}
//	catch (const out_of_range& e) {
//		cerr << "Out of range error: " << e.what() << endl; // 捕捉并处理越界访问异常
//	}
//	// 尝试访问越界元素
//	try {
//		cout << "Element at index 10 is " << vec.at(10) << endl; // 访问索引为 10 的元素，这将抛出异常
//	}
//	catch (const out_of_range& e) {
//		cerr << "Out of range error———— " << e.what() << endl; // 捕捉并处理越界访问异常
//	}
//
//	return 0; // 返回 0 表示程序正常结束
// }

void test_vector7()
{
    vector<int> v1;
    v1.push_back(1);
    v1.push_back(2);
    v1.push_back(3);
    v1.push_back(4);
    vector<int>::iterator it = v1.begin();
    while (it != v1.end())
    {
        *it -= 10;
        cout << *it << " ";
        it++;
    }
    cout << endl;
}

void test_vector8()
{
    vector<int> v;
    v.assign(10, 5);
    for (auto e : v)
    {
        cout << e << " ";
    }
    cout << endl;

    int arr[] = {1, 2, 3, 4, 5};
    v.assign(arr, arr + 3);
    for (auto e : v)
    {
        cout << e << " ";
    }
    cout << endl;

    vector<int> v3 = {6, 7, 8};
    v.assign(v3.begin(), v3.end());
    for (auto e : v)
    {
        cout << e << " ";
    }
    cout << endl;
}
#include <algorithm>
void test_vector9()
{
    vector<int> v1{1, 2, 3};
    vector<int> v2{4, 5, 6};

    // 使用 swap 交换两个 vector 的内容
    v1.swap(v2);

    cout << "After swapping:\n";
    cout << "v1: ";
    for (auto elem : v1)
    {
        cout << elem << " ";
    }
    cout << "\nv2: ";
    for (auto elem : v2)
    {
        cout << elem << " ";
    }
    cout << endl;
}
int main()
{
    test_vector9();

    return 0;
}

// void TestVectorExpandOP()
//{
//	vector<int> v;
//	size_t sz = v.capacity();
//	v.reserve(100); // 提前将容量设置好，可以避免一遍插入一遍扩容
//	cout << "making bar grow:\n";
//	for (int i = 0; i < 100; ++i)
//	{
//		v.push_back(i);
//		if (sz != v.capacity())
//		{
//			sz = v.capacity();
//			cout << "capacity changed: " << sz << '\n';
//		}
//	}
// }